package main

import (
	"fmt"
	"net"
	"time"
)

func handleConn(c net.Conn) {
	defer c.Close()
	for {
		//从连接中读取数据
		var buf = make([]byte, 128)
		//SetReadDeadline 方法接收一个绝对时间作为超时的 deadline，一旦设置了，
		//那么无论后续的Read操作是否超时，后面与这个socket有关的所有读操作都会返回超时失败错误。
		//如果要取消超时设置，可以使用 SetReadDeadline(time.Time{})
		c.SetReadDeadline(time.Now().Add(time.Second))
		n, err := c.Read(buf)
		if err != nil {
			fmt.Printf("conn read %d bytes, error: %s", n, err)
			if nerr, ok := err.(net.Error); ok && nerr.Timeout() {
				// 进行其他业务逻辑的处理
				continue
			}
			return
		}
		fmt.Printf("read %d bytes, content is %s\n", n, string(buf[:n]))
	}
}

func main() {
	//使用net包的Listen函数绑定服务器端口8888，并将它转换为监听状态
	l, err := net.Listen("tcp", ":8888")
	if err != nil {
		fmt.Println("listen error:", err)
		return
	}
	for {
		//Listen返回成功后，这个服务会进入一个循环,调用net.Listener 的 Accept 方法接收新客户端连接
		//在没有新连接的时候，这个服务会阻塞在 Accept 调用上，直到有客户端连接上来，Accept 方法将返回一个 net.Conn 实例,用于和新连上的客户端进行通信。
		c, err := l.Accept()
		if err != nil {
			fmt.Println("accept error:", err)
			break
		}

		//这个服务程序启动了一个新 Goroutine，并将 net.Conn 传给这个 Goroutine，这样这个Goroutine 就专门负责处理与这个客户端的通信了。
		go handleConn(c)
	}
}
